home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
pascal
/
gsdbloo.exe
/
GS_DBNTX.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-02-26
|
55KB
|
1,304 lines
unit GS_DBNtx;
{-----------------------------------------------------------------------------
Clipper Index Handler
GS_DBNtx Copyright (c) Richard F. Griffin
4 August 1991
102 Molded Stone Pl
Warner Robins, GA 31088
-------------------------------------------------------------
This unit handles the objects for all Clipper index (.NTX)
operations. This unit may be implemented by changing the
GS_DBASE.PAS unit's USES statement from GS_DBNDX to GS_DBNTX.
That's the only change necessary to replace .NDX indexes with
Clipper .NTX indexes.
changes:
02 Feb 92 - Added call to KeyLocRec in main part of KeyUpdate.
This allows multiple indexes to be used. In the past,
the program assumed the index was pointing to the
current record. There is a sacrifice in update
speed, however.
18 Feb 92 - Fixed numerous problems with KeyFind and KeyUpdate.
Corrected problem to ensure the first duplicate key
is retrieved. Corrected Index key insertion problem.
Added KeyBOF flag for test for access beyond top of
file.
19 Feb 92 - Embedded cache into Ndx_Get and Ndx_Put. A number
of node images will be stored to memory. This will
be treated as a stack, where the last page accessed
will be pushed to the top and new nodes will use the
bottom image. They will replace the old image and
push to the top. This allows the most active nodes to
remain in memory, with less active nodes being swapped
out. This also added a Ndx_Flush method to write all
updated nodes to disk on demand, such as at closing.
------------------------------------------------------------------------------}
interface
{$D-}
uses
GS_Strng, {String handler routines}
GS_Error, {Error handler routines}
GS_FileH; {File handler routines}
const
NdxBufSize = 4096;
IndexSignature = 'NTX';
NdxBufferedPages = 16;
type
{
┌──────────────────────────────────────────────────────────┐
│ ******** Index Header Description ******** │
└──────────────────────────────────────────────────────────┘
}
GS_Indx_Head = Record
Vers1,
Vers2 : Integer;
Root : Longint;
Unknwn1 : Longint;
Entry_Sz : Integer;
Key_Lgth : Integer;
Unknwn2 : Integer;
Max_Keys : Integer;
Min_Keys : Integer;
Key_Form : array [0..1001] of char;
end;
{
┌──────────────────────────────────────────────────────────┐
│ ******** Index Node Header Description ******** │
└──────────────────────────────────────────────────────────┘
}
GS_Indx_Data = Record {300 additional bytes for overflow}
case integer of
0 : (Data_Ary : array [0..1323] of byte);
1 : (Indx_Ary : array [0..661] of word);
2 : (Entry_Ct : Integer);
end;
GS_Indx_EntPtr = ^GS_Indx_Etry;
{
┌──────────────────────────────────────────────────────────┐
│ ******** Index Node Key Entry Description ******* │
└──────────────────────────────────────────────────────────┘
}
GS_Indx_Etry = Record
Block_Ax : Longint;
Recrd_Ax : Longint;
Char_Fld : array [1..255] of char;
end;
GS_Indx_Tabl = Record
Page_No : Longint; {Disk block holding node info}
Etry_No : Longint; {Last entry used in node}
Last_One : Longint; {Number of keys in this node }
Node_Pag : Boolean; {True for non-leaf nodes}
end;
GS_Indx_LPtr = ^GS_dBase_IX; {Pointer to object. Used by GS_dBase_DB}
GS_DiskPagPtr = ^GS_DiskPagBfr;
GS_DiskPagBfr = array[0..1023] of byte;
GS_DiskTblPtr = ^GS_DiskTblPag;
GS_DiskTblPag = record
BlkNum : longint;
BlkWrt : boolean;
BlkPtr : GS_DiskPagPtr;
end;
{
┌─────────────────────────────────┐
│ GS_dBase_IX Object Definition │
└─────────────────────────────────┘
}
GS_dBase_IX = object
Ndx_Name : String[64]; {File name of index file}
Ndx_Hdr : GS_Indx_Head; {Index header information}
Ndx_File : file; {File type for index file}
Ndx_Tabl : array [0..25] of GS_Indx_Tabl;
{Array of 25 table entries to hold}
{the trail of non-leaf nodes that are}
{traversed during a key search. This }
{table is needed to track positions for}
{sequential reads (next and previous).}
Ndx_Lvl : integer; {Holds counter into Ndx_Tabl}
Ndx_Data : GS_Indx_Data; {Node header information}
Ndx_Pntr : GS_Indx_EntPtr; {Pointer to key entry information}
Ndx_Key_St : string[255]; {Holds last key value found on call to}
{either KeyRead or KeyFind}
Ndx_Key_Num : longint; {Holds last physical record number for a}
{key value found on call to either}
{KeyRead or KeyFind}
Ndx_Key_Form : string[127]; {Holds the key formula in type string}
KeyBOF : boolean;
KeyEOF : boolean; {True if last KeyRead attempted to read}
{beyond the range of index keys - either}
{beyond beginning or end of file}
ExactMatch : boolean; {Flag for type of test to use in KeyFind}
{It will force a match against an entire}
{key if true, and only for the length of}
{the passed argument if false. It is}
{initialized true.}
Ndx_PagArray : array[0..NdxBufferedPages-1] of GS_DiskTblPag;
CONSTRUCTOR Init(IName : String);
CONSTRUCTOR Ndx_Make(filname,formla: string;lth: integer;typ: char);
DESTRUCTOR Done;
FUNCTION KeyFind(st : String) : longint;
FUNCTION KeyLocRec(rec : longint) : boolean;
FUNCTION KeyRead(a : LongInt) : longint;
PROCEDURE KeyUpdate (st : string; rec, crec : longint);
PROCEDURE Ndx_Close;
Procedure Ndx_Flush;
PROCEDURE Ndx_Get(blk : longint);
PROCEDURE Ndx_GetRecEntry;
PROCEDURE Ndx_GetRecPage(Ascnd : boolean);
FUNCTION Ndx_LastEntry : boolean;
PROCEDURE Ndx_NodeData(pn, en, lo : longint; np : boolean);
PROCEDURE Ndx_Put(blk : longint);
Procedure KeyList(st : string);
FUNCTION SetMatchValue(st : string): string;
end;
{.pa}
{
┌──────────────────────────┐
│ IMPLEMENTATION SECTION │
└──────────────────────────┘
}
implementation
const
Node_Size = 1024; {Size of the node}
Next_Record = -1; {Token value passed to read next record}
Prev_Record = -2; {T